
#line 1 "lexer.rl"
//https://gist.github.com/iwillspeak/cd27b740d658a6f38c8c

#include <string>
#include <iostream>

#define CAPTURE_TOKEN(t) \
token->value = std::string(ts, te-ts); \
token->type = Token::t


#line 32 "lexer.rl"



static const int ExampleLexer_start = 1;
static const int ExampleLexer_first_final = 1;
static const int ExampleLexer_error = 0;

static const int ExampleLexer_en_main = 1;

static const char _ExampleLexer_nfa_targs[] = {
	0, 0
};

static const char _ExampleLexer_nfa_offsets[] = {
	0, 0, 0, 0, 0, 0
};

static const char _ExampleLexer_nfa_push_actions[] = {
	0, 0
};

static const char _ExampleLexer_nfa_pop_trans[] = {
	0, 0
};


#line 35 "lexer.rl"


struct Token
{
	enum TokenType {
		Var,
		Num,
		Plus,
		End,
		None
	};
	
	TokenType type;
	std::string value;
};

class Lexer
{
	public:
	Lexer(std::string input)
	: buffer(input) {
		
		
		{
			cs = (int)ExampleLexer_start;
			ts = 0;
			te = 0;
		}
		
		#line 57 "lexer.rl"
		
		
		// set up the buffer here
		p = buffer.c_str();
		pe = p + buffer.size();
		eof = pe;
	}
	
	Token* next() {
		auto token = new Token();
		
		token->type = Token::None;
		
		do {
			
			if (cs >= ExampleLexer_first_final) {
				token->type = Token::End;
			}
			
			
			{
				if ( p == pe )
				goto _test_eof;
				switch ( cs )
				{
					case 1:
					goto st_case_1;
					case 0:
					goto st_case_0;
					case 2:
					goto st_case_2;
					case 3:
					goto st_case_3;
					case 4:
					goto st_case_4;
				}
				goto st_out;
				ctr2:
				{
					#line 25 "lexer.rl"
					{te = p+1;{
							#line 25 "lexer.rl"
							
							CAPTURE_TOKEN(Plus);
							{p+= 1; cs = 1; goto _out;}
						}}}
				
				goto st1;
				ctr6:
				{
					#line 1 "-"
					{te = p;p = p - 1;}}
				
				goto st1;
				ctr8:
				{
					#line 15 "lexer.rl"
					{te = p;p = p - 1;{
							#line 15 "lexer.rl"
							
							CAPTURE_TOKEN(Num);
							{p+= 1; cs = 1; goto _out;}
						}}}
				
				goto st1;
				ctr10:
				{
					#line 20 "lexer.rl"
					{te = p;p = p - 1;{
							#line 20 "lexer.rl"
							
							CAPTURE_TOKEN(Var);
							{p+= 1; cs = 1; goto _out;}
						}}}
				
				goto st1;
				st1:
				{
					#line 1 "NONE"
					{ts = 0;}}
				p+= 1;
				if ( p == pe )
				goto _test_eof1;
				st_case_1:
				{
					#line 1 "NONE"
					{ts = p;}}
				switch( ( (*( p))) ) {
					case 32: {
						goto st2;
					}
					case 43: {
						goto ctr2;
					}
				}
				if ( ( (*( p))) < 48 ) {
					if ( 9 <= ( (*( p))) && ( (*( p))) <= 13 ) {
						goto st2;
					}
				} else if ( ( (*( p))) > 57 ) {
					if ( ( (*( p))) > 90 ) {
						if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
							goto st4;
						}
					} else if ( ( (*( p))) >= 65 ) {
						goto st4;
					}
				} else {
					goto st3;
				}
				{
					goto st0;
				}
				st_case_0:
				st0:
				cs = 0;
				goto _out;
				st2:
				p+= 1;
				if ( p == pe )
				goto _test_eof2;
				st_case_2:
				if ( ( (*( p))) == 32 ) {
					goto st2;
				}
				if ( 9 <= ( (*( p))) && ( (*( p))) <= 13 ) {
					goto st2;
				}
				{
					goto ctr6;
				}
				st3:
				p+= 1;
				if ( p == pe )
				goto _test_eof3;
				st_case_3:
				if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
					goto st3;
				}
				{
					goto ctr8;
				}
				st4:
				p+= 1;
				if ( p == pe )
				goto _test_eof4;
				st_case_4:
				if ( ( (*( p))) < 65 ) {
					if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
						goto st4;
					}
				} else if ( ( (*( p))) > 90 ) {
					if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
						goto st4;
					}
				} else {
					goto st4;
				}
				{
					goto ctr10;
				}
				st_out:
				_test_eof1: cs = 1; goto _test_eof; 
				_test_eof2: cs = 2; goto _test_eof; 
				_test_eof3: cs = 3; goto _test_eof; 
				_test_eof4: cs = 4; goto _test_eof; 
				
				_test_eof: {}
				if ( p == eof )
				{
					switch ( cs ) {
						case 2: goto ctr6;
						case 3: goto ctr8;
						case 4: goto ctr10;
					}
				}
				
				_out: {}
			}
			
			#line 76 "lexer.rl"
			
			
			if (cs == ExampleLexer_error) {
				token->type = Token::None;
				return token;
			}
			
		} while (token->type == Token::None);
		
		return token;
	}
	
	private:
	// buffer state
	const char* p, * pe, * eof;
	// current token
	const char* ts, * te;
	// machine state
	int act, cs, top, stack[1];
	
	std::string buffer;
};


int main(int argc, const char* argv[]) {
	
	auto lex = Lexer("test + 123");
	Token* token;
	
	do {
		token = lex.next();
		
		std::cout << "<" << token->value << ">" << std::endl;
		
	} while (token->type != Token::None &&
	token->type != Token::End);
}
